package com.angel.architecture.flex.interceptors;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import com.angel.architecture.persistence.base.PersistentObject;
import com.angel.common.helpers.ReflectionHelper;


/**
 *
 * @author William
 */
public class PropertiesUpdater {
	
	private List<Object> parametersUpdated = new ArrayList<Object>();
  
	@SuppressWarnings("unchecked")
	public void updateProperties(Object param) {
		if(param == null || (ReflectionHelper.isAJavaPrimitiveClass(param.getClass())) || 
			(!ReflectionHelper.isAJavaPrimitiveClass(param.getClass()) && parametersUpdated.contains(param))){
			//Si es una tipo basico, o ya fue actualizado retorno.
			return;
		}
		parametersUpdated.add(param);
		if(ReflectionHelper.inheritClassFrom(param.getClass(), PersistentObject.class)){
			this.doUpdateProperties((PersistentObject) param);
		}
		if(ReflectionHelper.implementsInterfaceRecursive(param.getClass(), Collection.class)){
			Collection<Object> collection = (Collection<Object>) param;
			if(collection.size() > 0 && ReflectionHelper.inheritClassFrom(collection.iterator().next().getClass(), PersistentObject.class)){
				Iterator<Object> i = collection.iterator();
				while(i.hasNext()){
					this.doUpdateProperties((PersistentObject) i.next());
				}
				
			}
		}
    }
	private void updateObjectAttrbitues(Object param){
		Field[] paramFields = ReflectionHelper.getFieldsDeclaredFor(param.getClass());
		for(Field field: paramFields){
			Object paramFieldObject = ReflectionHelper.getFieldValue(param, field);
			this.updateProperties(paramFieldObject);
		}
	}
	
	private void doUpdateProperties(PersistentObject persistentObject){
		if(persistentObject.getCreationDate() == null || persistentObject.getId() == null){
			persistentObject.updateNullAttributes();
		}
		this.updateObjectAttrbitues(persistentObject);
	}
}